﻿using System;
using System.Diagnostics;

namespace PlantsZombies.Common
{
    public unsafe class RandomSpeciesType
    {
        private readonly Random random;
        private readonly int _maxTime; // 设置一个时间阈值，超过这个时间后概率会调整
        private int _currentTime; // 当前时间，用于调整概率
        readonly int _number = 3;
        public RandomSpeciesType(int _maxTime, int n)
        {
            this.random = new Random();
            this._maxTime = _maxTime;
            this._currentTime = 0;
            _number = n;
        }
        public SpeciesType GenerateNumber()
        {
            if (++_currentTime <= 5) return SpeciesType.OrdinaryZombie;

            if (_currentTime >= _maxTime) // 每次调用时增加当前时间
                _currentTime = (int)(_maxTime * 0.75f);

            double[] probabilities = CalculateProbabilities(_currentTime);
            double randomValue = random.NextDouble();

            // 根据概率决定生成的数字
            fixed(double* ptr= probabilities)
            {
                for (int i = 0; i < probabilities.Length; i++)
                {
                    if (randomValue < *(ptr+ i))
                        return GetSpeciesType(i + 1);
                    randomValue -= *(ptr + i);
                }
            }

            return GetSpeciesType(_number + 1);
        }
        private SpeciesType GetSpeciesType(int i)
        {
            int code = SpeciesType.OrdinaryZombie.GetHashCode();
            int sp = code - 1;
            return (SpeciesType)(i + sp);
        }
        private double[] CalculateProbabilities(int time)
        {
            double[] probabilities = new double[_number];
            double total = 0;

            // 计算每个数字的概率
            fixed(double* ptr= probabilities)
            {
                for (int i = 1; i <= _number; i++)
                {
                    double probability = CalculateProbability(i, time);
                    *(ptr + i - 1) = probability;
                    total += probability;
                }
                // 归一化概率
                for (int i = 0; i < probabilities.Length; i++)
                {
                    *(ptr + i) /= total;
                }
            }

            return probabilities;
        }

        private double CalculateProbability(int number, int time)
        {
            // 随着时间增加，较小的数字的概率减少，较大的数字的概率增加
            return Math.Pow(1.0 * time / _maxTime, number);
        }
    }
}
